﻿namespace HideAndSeek
{
    abstract class Location
    {
        public string Name { get; private set; }

        public Location[] Exits;

        public Location(string name)
        {
            Name = name;
        }

        public virtual string Description
        {
            get
            {
                string description = "You're standing in the " + Name +
                                     ". You see exits to the following places: ";
                for (var i = 0; i < Exits.Length; i++)
                {
                    description += " " + Exits[i].Name;
                    if (i != Exits.Length - 1)
                    {
                        description += ",";
                    }
                }
                description += ".";

                return description;
            }
        }
    }

    interface IHasExteriorDoor
    {
        string DoorDescription { get; }

        Location DoorLocation { get; set; }
    }

    class Room : Location
    {
        private string _decoration;

        public Room(string name, string decoration) : base(name)
        {
            _decoration = decoration;
        }

        public override string Description => base.Description + " You see " + _decoration + ".";
    }

    class RoomWithDoor : RoomWithHidingPlace, IHasExteriorDoor
    {
        public string DoorDescription { get; private set; }

        public Location DoorLocation { get; set; }

        public RoomWithDoor(string name, string decoration, string hidingPlaceName, string doorDescription) : base(name, decoration, hidingPlaceName)
        {
            DoorDescription = doorDescription;
        }
    }

    class Outside : Location
    {
        private bool _hot;

        public Outside(string name, bool hot) : base(name)
        {
            _hot = hot;
        }

        public override string Description
        {
            get
            {
                string newDescription = base.Description;
                if (_hot)
                {
                    newDescription += " It's very hot.";
                }
                return newDescription;
            }
        }
    }

    class OutsideWithDoor : Outside, IHasExteriorDoor
    {
        public string DoorDescription { get; private set; }

        public Location DoorLocation { get; set; }

        public OutsideWithDoor(string name, bool hot, string doorDescription) : base(name, hot)
        {
            DoorDescription = doorDescription;
        }

        public override string Description => base.Description + " You see " + DoorDescription + ".";
    }

    interface IHidingPlace
    {
        string HidingPlaceName { get; }
    }

    class RoomWithHidingPlace : Room, IHidingPlace
    {
        public string HidingPlaceName { get; }

        public RoomWithHidingPlace(string name, string decoration, string hidingPlaceName) : base(name, decoration)
        {
            HidingPlaceName = hidingPlaceName;
        }

        public override string Description => base.Description + " Someone could hide " + HidingPlaceName + ".";
    }

    class OutsideWithHidingPlace : Outside, IHidingPlace
    {
        public string HidingPlaceName { get; }

        public OutsideWithHidingPlace(string name, bool hot, string hidingPlaceName) : base(name, hot)
        {
            HidingPlaceName = hidingPlaceName;
        }

        public override string Description => base.Description + " Someone could hide " + HidingPlaceName + ".";
    }
}
